package com.simple.datax.transport.webservice;

import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.List;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;

import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.configuration.security.FiltersType;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.log4j.Logger;

public class WebServiceConnClient {
	private static final Logger logger = Logger.getLogger(WebServiceConnClient.class);
	private static final QName SERVER_NAME = new QName(
			"http://webservice.transport.datax.simple.com/", "WebServiceConn");
	private static final QName PORT_NAME = new QName(
			"http://webservice.transport.datax.simple.com/",
			"WebServiceConnPort");

//	private String serviceURL;
//	boolean ssl;
//	WebServiceConn wsProxy;
//	public WebServiceConnClient(String serviceURL, boolean ssl) {
//		this.serviceURL = serviceURL;
//		this.ssl = ssl;
//		init();
//	}
//
//	private void init() {
//		
//	}
	
	public static WebServiceConn getWSProxy(String serviceURL, boolean ssl) {
		Service service = Service.create(SERVER_NAME);
		String endpointAddress = serviceURL;
		service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING,
				endpointAddress);
		WebServiceConn wsProxy = service.getPort(WebServiceConn.class);
		if (ssl) {
			configureSSLOnClient(wsProxy);
		}
		return wsProxy;
	}
	
	public static void main(String[] args) {
		boolean ssl = false;
		String protocal = "http://localhost:8080";
		if (args.length != 1) {
			logger.error("[Usage] java WebServiceConnClient enableSSL:");
			logger.error(" enableSSL option:");
			logger.error(" 1: enable");
			logger.error(" else : disable");
			return;
		}
		if (args[0].equals("1")) {
			ssl = true;
			protocal = "https://localhost:8443";
		}
		Service service = Service.create(SERVER_NAME);
		String endpointAddress = protocal + "/datax_service/services/WebServiceConn";
		service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING,
				endpointAddress);

		WebServiceConn hw = service.getPort(WebServiceConn.class);
		if (ssl) {
			configureSSLOnClient(hw);
		}

		// 发送报文数据
		String ret = hw.sendData("EC111111", "tester", "测试内容");
		// 返回值为null，表示调用web service成功
		if (ret == null) {
			System.out.println("1.报文发送成功");

			// 列出所有可接收报文
			javax.xml.ws.Holder<List<String>> result = new javax.xml.ws.Holder<List<String>>();
			ret = hw.getDataList("EC111111", "tester", result);

			// 返回值为null，表示调用web service成功
			if (ret == null) {

				// 从 result.value中读出报文列表
				if (result.value != null && result.value.size() > 0) {
					System.out.println("2.接收报文列表:");

					for (String str : result.value) {
						System.out.println(str);
					}

					// 读取单个报文内容
					javax.xml.ws.Holder<byte[]> data = new javax.xml.ws.Holder<byte[]>();
					ret = hw.getData("EC111111", "tester",
							result.value.get(result.value.size() - 1), data);

					// 返回值为null，表示调用web service成功
					if (ret == null) {
						String content = new String(data.value);
						System.out.println("3.测试报文列表中最后一个报文的内容:");
						System.out.println(content);
						return;
					}
				} else {
					System.out.println("2.没有可接收报文");
					return;
				}
			}
		}
		System.out.println(ret);
	}

	private static void configureSSLOnClient(Object obj) {
		File file = new File("D:\\tomcat6\\conf\\tomcat.keystore");

		Client client = ClientProxy.getClient(obj);
		HTTPConduit httpConduit = (HTTPConduit) client.getConduit();

		try {
			TLSClientParameters tlsParams = new TLSClientParameters();
			tlsParams.setDisableCNCheck(true);

			KeyStore keyStore = KeyStore.getInstance("JKS");
			String password = "111111";
			String storePassword = "111111";

			keyStore.load(new FileInputStream(file),
					storePassword.toCharArray());
			TrustManagerFactory trustFactory = TrustManagerFactory
					.getInstance(TrustManagerFactory.getDefaultAlgorithm());
			trustFactory.init(keyStore);
			TrustManager[] trustManagers = trustFactory.getTrustManagers();
			tlsParams.setTrustManagers(trustManagers);

			keyStore.load(new FileInputStream(file),
					storePassword.toCharArray());
			KeyManagerFactory keyFactory = KeyManagerFactory
					.getInstance(KeyManagerFactory.getDefaultAlgorithm());
			keyFactory.init(keyStore, password.toCharArray());
			KeyManager[] keyManagers = keyFactory.getKeyManagers();
			tlsParams.setKeyManagers(keyManagers);

			FiltersType filtersTypes = new FiltersType();
			filtersTypes.getInclude().add(".*_EXPORT_.*");
			filtersTypes.getInclude().add(".*_EXPORT1024_.*");
			filtersTypes.getInclude().add(".*_WITH_DES_.*");
			filtersTypes.getInclude().add(".*_WITH_NULL_.*");
			filtersTypes.getExclude().add(".*_DH_anon_.*");
			tlsParams.setCipherSuitesFilter(filtersTypes);

			httpConduit.setTlsClientParameters(tlsParams);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
